<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 1. 通过函数创建的对象和函数没有关系(简单来说不是构造函数创建)
    // var arr = [1, 2, 3];  // new Array()
    // var obj = { a: 1, b: 2 };// new Object()

    // console.log(arr instanceof Array); // true  arr是由构造函数Array创建的
    // console.log(obj instanceof Object); // true  obj是由构造函数Object创建的

    // 如果期望创建的对象 和 创建该对象的函数有关系 => 该函数需要是一个构造函数?


    // 那么普通函数和构造函数有什么区别?

    // String()  Number()  Boolean()

    // 作为普通函数调用  => 直接调用 =>  函数名()
    // console.log(String("100"));
    // console.log(Number("100"));
    // console.log(Boolean("100"));

    // 作为构造函数    => 配合new关键词调用 => 得到一个对象(实例化对象)
    // console.log(new String("100"));
    // console.log(new Number("100"));
    // console.log(new Boolean("100"));

    // 注意:
    // 实例化是指在面向对象的编程中，把用类(构造函数)创建对象的过程称为实例化
    // 构造函数创建的对象也可以叫做实例化对象

    // 对比发现:
    // 1. 其实所谓的普通函数和构造函数 其实都是函数,只是调用的方式不一样
    // 2. 构造函数的结果和普通函数不一样 -> new关键词的功劳


    // new 关键词做了哪些操作?
    // 1. 创建一个纯净的实例化对象 {}
    // 2. 给创建的实例化对象绑定原型属性 [[Prototype]] / __proto__(老版本) 指向构造函数的原型对象
    //    {}[[Prototype]] = 构造函数.prototype (公有属性和方法) 新版本
    //    {}.__proto__ = 构造函数.prototype (公有属性和方法)   老版本

    //    可以理解为 所有的实例化对象 都有原型属性[[Prototype]] 指向 构造函数的原型对象 (即所有的实例化对象都可以通过原型属性[[Prototype]] 访问构造函数的原型对象  )

    // 3. 将this指向创建的实例化对象  this -> {}  (操作this,操作创建的实例化对象)
    // 4. 默认返回被创建的实例化对象

    // 注意:
    // a. 每次调用构造函数 -> 执行构造函数的上下文 -> 创建新的实例化对象(一般)
    // b. 构造函数中的this -> 本次构造函数执行过程中创建的实例化对象
    // c. 为了区分普通函数和构造函数 -> 建议构造函数首字母大写



    // 作为普通函数调用
    // function fn() {
    //     console.log("函数被调用");
    //     console.log("this指向:", this);
    // }

    // var result = fn();  // this -> window
    // console.log(result); // undefined


    // 作为构造函数调用
    // function Fn() {
    //     // {}  创建一个纯净的实例化对象
    //     // this -> {}
    //     console.log("函数被调用");
    //     console.log("this指向:", this);
    //     console.log(this instanceof Fn);  //true (在构造函数内部创建的)

    //     // 我们可以做的操作 把需要的属性和方法绑定到实例化对象上

    //     // return this;   // 返回创建的实例化对象
    // }

    // // 每次调用构造函数 -> 执行构造函数的上下文 -> 创建实例化对象  -> 绑定实例化对象的属性 -> 返回创建的实例化对象
    // 变量 result 引用被创建的实例化对象
    // var result = new Fn();  // this -> window
    // console.log("result", result); // {}

    // var res = new Fn();  // this -> window
    // console.log("result", res); // {}

    // console.log(result === res);



    // -----------------------------------

    function Fn(a, b) {
        // {}

        // {}[[Prototype]] = Fn.prototype;

        // this -> {}

        // 我们可以做的操作 把需要的属性和方法绑定到实例化对象上
        this.a = a;
        this.b = b;
        this.sum = function () {
            return this.a + this.b;
        }

        // return this;
    }

    var obj1 = new Fn(1, 2);
    console.log(obj1);

    var obj1 = new Fn(10, 20);
    console.log(obj1);


















</script>

</html>